using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Resources;
using System.Runtime.InteropServices;

using AudioDjStudio;
using Ctl3d;


namespace IntelliTouchMix
{
	public partial class FormMain : Form
    {

		public FormMain()
		{
			InitializeComponent();
            initUserCode();
		}
        public AudioDjStudio.AudioDjStudio audioDjStudio1;


		internal Int16	m_selOutputMaster = 0;
		internal Int16	m_selOutputMonitor = 0;
		internal Int16	m_selSpeakersMaster = 0;
		internal Int16	m_selSpeakersMonitor = 0;
		
		internal Int16	DECKA_PLAYER = 0;
		internal Int16	DECKB_PLAYER = 1;
		internal Int16	PLAYLIST_PLAYER = 2;
        internal Int16  SAMPLE1_PLAYER = 3;
        internal Int16  SAMPLE2_PLAYER = 4;

		internal Int16	CUE_POINT_PLAYER1_1 = 11;
		internal Int16	CUE_POINT_PLAYER1_2 = 12;
		internal Int16	CUE_POINT_PLAYER1_3 = 13;

		internal Int16	CUE_POINT_PLAYER2_1 = 21;
		internal Int16	CUE_POINT_PLAYER2_2 = 22;
		internal Int16	CUE_POINT_PLAYER2_3 = 23;

		internal Int32	m_nScrollingWaveformViewInMs = 10000;

		IntPtr[]	m_hWndVuMeterLeft = new IntPtr[3];
		IntPtr[]	m_hWndVuMeterRight = new IntPtr[3];

		Int32[]		m_nTotalWavePeaks = new Int32[2];
		float[]		m_fPeakDurationInMs = new float[2];

		Int32[]		m_nCurrentPosInPixels = new Int32[5];

		Int32[]		m_nWaveformScrollStartPosInMs = new Int32[2];
		Int32[]		m_nWaveformScrollEndPosInMs = new Int32[2];

		bool[]		m_bMustResumeOnMouseUp = new bool[2];
		Int32[]		m_nPixelPositionOnWaveform = new Int32[2];

		FormEqualizerA frmEqualizerA = new FormEqualizerA();
		FormEqualizerB frmEqualizerB = new FormEqualizerB();
        FormEffects form1 = new FormEffects();
        FormEvents formEvents = new FormEvents();

		bool[]		m_bEnableRefreshWaveformFull = new bool[2];
		bool[]		m_bEnableRefreshWaveformScroll = new bool[2];

		private void DrawWaveformFull(Int16 nPlayerIndex, PictureBox pictureBox, int nCurrentPosInPixels)
		{
			if (audioDjStudio1.GetPlayerStatus(nPlayerIndex) == enumPlayerStatus.SOUND_NONE)
				return;

			// obtain the Device Context of the pictureBox control
			Graphics graphics = Graphics.FromHwnd(pictureBox.Handle);
			IntPtr hDC = graphics.GetHdc();

			// show the full waveform
			audioDjStudio1.DisplayWaveform.BitmapViewDrawToHdc(nPlayerIndex, hDC, 0, 0,
									pictureBox.Width, pictureBox.Height, enumWaveformStereoModes.STEREO_MODE_CHANNELS_MIXED,
									true, true, 0, -1);

			// release the Device Context before performing any further drawing
			graphics.ReleaseHdc();

			// draw the current position line in white
			Pen penPosition = new Pen(Color.White, 2);
			graphics.DrawLine(penPosition, nCurrentPosInPixels, 0, nCurrentPosInPixels, pictureBox.Height);
			penPosition.Dispose();
			graphics.Dispose();

			if (m_bEnableRefreshWaveformFull[nPlayerIndex])
				m_bEnableRefreshWaveformFull[nPlayerIndex] = false;
		}

		private void DrawWaveformScrolling(Int16 nPlayerIndex, PictureBox pictureBox)
		{
			if (audioDjStudio1.GetPlayerStatus(nPlayerIndex) == enumPlayerStatus.SOUND_NONE)
				return;

			// obtain the Device Context of the pictureBoxScrolling control
			Graphics graphics = Graphics.FromHwnd(pictureBox.Handle);
			IntPtr hDC = graphics.GetHdc();

			// show a waveform view with the current playback position on the center of the picture control
			enumScaleUnits nScaleUnits = audioDjStudio1.ScaleUnits;
			audioDjStudio1.ScaleUnits = enumScaleUnits.SCALE_MILLISECONDS;			
			Int32 nCurrentPositionInMs = audioDjStudio1.GetCurrentPos(nPlayerIndex);
			m_nWaveformScrollStartPosInMs[nPlayerIndex] = nCurrentPositionInMs - (m_nScrollingWaveformViewInMs / 2);
			m_nWaveformScrollEndPosInMs[nPlayerIndex] = nCurrentPositionInMs + (m_nScrollingWaveformViewInMs / 2);
			audioDjStudio1.ScaleUnits = nScaleUnits;
			audioDjStudio1.DisplayWaveform.BitmapViewDrawToHdc(nPlayerIndex, hDC, 0, 0,
									pictureBox.Width, pictureBox.Height, enumWaveformStereoModes.STEREO_MODE_CHANNELS_MIXED,
									true, true, m_nWaveformScrollStartPosInMs[nPlayerIndex], m_nWaveformScrollEndPosInMs[nPlayerIndex]);

			// release the Device Context before performing any further drawing
			graphics.ReleaseHdc();

			// draw the current position line in white
			Pen penPosition = new Pen(Color.White, 2);
			int xPos = (int)pictureBox.Width / 2;
			graphics.DrawLine(penPosition, xPos, 0, xPos, pictureBox.Height);
			penPosition.Dispose();
			graphics.Dispose();

			if (m_bEnableRefreshWaveformScroll[nPlayerIndex])
				m_bEnableRefreshWaveformScroll[nPlayerIndex] = false;
		}


		private IntPtr CreateVuMeter(PictureBox ctrlPosition)
		{
			// create a new graphic bar
			IntPtr hWnd = audioDjStudio1.GraphicBarsManager.Create(this.Handle, ctrlPosition.Left, ctrlPosition.Top,
				ctrlPosition.Width, ctrlPosition.Height);

			// set graphic bar range
			audioDjStudio1.GraphicBarsManager.SetRange(hWnd, 0, 32767);

			// enable automatic drop and set the requested orientation
			GRAPHIC_BAR_SETTINGS settings = new GRAPHIC_BAR_SETTINGS();
			audioDjStudio1.GraphicBarsManager.GetGraphicalSettings(hWnd, ref settings);
			settings.bAutomaticDrop = true;
			settings.nOrientation = enumGraphicBarOrientations.GRAPHIC_BAR_ORIENT_VERTICAL;
			audioDjStudio1.GraphicBarsManager.SetGraphicalSettings(hWnd, settings);

			return hWnd;
		}

		private void SetButtonsBitmaps()
		{
			// all of these bitmaps could be added at design-time using the
			// Picture and PictureMouseOver properties of the Ctl3d buttons;
			// in this case, being a demo program that could be edited by the user,
			// we prefer storing them inside application's resources

			// set normal state bitmaps
			SmartBitmap bmpStopWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Stop_w);
			BtnInfo1.SetPictureFromHandle(Pictures.Normal, bmpStopWhite.m_hBitmap);
			BtnInfo2.SetPictureFromHandle(Pictures.Normal, bmpStopWhite.m_hBitmap);
			BtnStop1.SetPictureFromHandle(Pictures.Normal, bmpStopWhite.m_hBitmap);
			BtnStop2.SetPictureFromHandle(Pictures.Normal, bmpStopWhite.m_hBitmap);
			BtnStopMonitor.SetPictureFromHandle(Pictures.Normal, bmpStopWhite.m_hBitmap);

			SmartBitmap bmpPlayWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Play_w);
			BtnPlay1.SetPictureFromHandle(Pictures.Normal, bmpPlayWhite.m_hBitmap);
			BtnPlay2.SetPictureFromHandle(Pictures.Normal, bmpPlayWhite.m_hBitmap);
			BtnPlayMonitor.SetPictureFromHandle(Pictures.Normal, bmpPlayWhite.m_hBitmap);

			SmartBitmap bmpPlayRevWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Play_rev_w);
			BtnPlayRev1.SetPictureFromHandle(Pictures.Normal, bmpPlayRevWhite.m_hBitmap);
			BtnPlayRev2.SetPictureFromHandle(Pictures.Normal, bmpPlayRevWhite.m_hBitmap);

			SmartBitmap bmpPauseWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Pause_w);
			BtnPause1.SetPictureFromHandle(Pictures.Normal, bmpPauseWhite.m_hBitmap);
			BtnPause2.SetPictureFromHandle(Pictures.Normal, bmpPauseWhite.m_hBitmap);
			BtnPauseMonitor.SetPictureFromHandle(Pictures.Normal, bmpPauseWhite.m_hBitmap);

			SmartBitmap bmpRewWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Rew_w);
			BtnRewMonitor.SetPictureFromHandle(Pictures.Normal, bmpRewWhite.m_hBitmap);

			SmartBitmap bmpForwWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Forw_w);
			BtnForwMonitor.SetPictureFromHandle(Pictures.Normal, bmpForwWhite.m_hBitmap);

			SmartBitmap bmpPrevWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Prev_w);
			BtnPrevMonitor.SetPictureFromHandle(Pictures.Normal, bmpPrevWhite.m_hBitmap);

			SmartBitmap bmpNextWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Next_w);
			BtnNextMonitor.SetPictureFromHandle(Pictures.Normal, bmpNextWhite.m_hBitmap);

			// set mouse over state bitmaps
			SmartBitmap bmpStopBlack = new SmartBitmap(IntelliTouchMix.Properties.Resources.Stop_b);
			BtnStop1.SetPictureFromHandle(Pictures.MouseOver, bmpStopBlack.m_hBitmap);
			BtnStop2.SetPictureFromHandle(Pictures.MouseOver, bmpStopBlack.m_hBitmap);
			BtnStopMonitor.SetPictureFromHandle(Pictures.MouseOver, bmpStopBlack.m_hBitmap);

			SmartBitmap bmpPlayBlack = new SmartBitmap(IntelliTouchMix.Properties.Resources.Play_b);
			BtnPlay1.SetPictureFromHandle(Pictures.MouseOver, bmpPlayBlack.m_hBitmap);
			BtnPlay2.SetPictureFromHandle(Pictures.MouseOver, bmpPlayBlack.m_hBitmap);
			BtnPlayMonitor.SetPictureFromHandle(Pictures.MouseOver, bmpPlayBlack.m_hBitmap);

			SmartBitmap bmpPlayRevBlack = new SmartBitmap(IntelliTouchMix.Properties.Resources.Play_rev_B);
			BtnPlayRev1.SetPictureFromHandle(Pictures.MouseOver, bmpPlayRevBlack.m_hBitmap);
			BtnPlayRev2.SetPictureFromHandle(Pictures.MouseOver, bmpPlayRevBlack.m_hBitmap);

			SmartBitmap bmpPauseBlack = new SmartBitmap(IntelliTouchMix.Properties.Resources.Pause_b);
			BtnPause1.SetPictureFromHandle(Pictures.MouseOver, bmpPauseBlack.m_hBitmap);
			BtnPause2.SetPictureFromHandle(Pictures.MouseOver, bmpPauseBlack.m_hBitmap);
			BtnPauseMonitor.SetPictureFromHandle(Pictures.MouseOver, bmpPauseBlack.m_hBitmap);

			SmartBitmap bmpRewBlack = new SmartBitmap(IntelliTouchMix.Properties.Resources.Rew_b);
			BtnRewMonitor.SetPictureFromHandle(Pictures.MouseOver, bmpRewBlack.m_hBitmap);

			SmartBitmap bmpForwBlack = new SmartBitmap(IntelliTouchMix.Properties.Resources.Forw_b);
			BtnForwMonitor.SetPictureFromHandle(Pictures.MouseOver, bmpForwBlack.m_hBitmap);

			SmartBitmap bmpPrevBlack = new SmartBitmap(IntelliTouchMix.Properties.Resources.Prev_b);
			BtnPrevMonitor.SetPictureFromHandle(Pictures.MouseOver, bmpPrevBlack.m_hBitmap);

			SmartBitmap bmpNextBlack = new SmartBitmap(IntelliTouchMix.Properties.Resources.Next_b);
			BtnNextMonitor.SetPictureFromHandle(Pictures.MouseOver, bmpNextBlack.m_hBitmap);
		}

		internal void PlayListAddItem(Int16 nPlayer)
		{
			int nItems = audioDjStudio1.PlayListGetCount(nPlayer);
		        
			PlayList1.Items.Clear ();

			for (Int16 nCount = 0; nCount < nItems; nCount++)
			{
				int nCounter = nCount + 1;
				string strItem;
				string strCounter;
				strCounter = nCounter.ToString();
				strItem = strCounter + "\t" + "[";
				strItem += audioDjStudio1.PlayListGetItemString(nPlayer, nCount, enumPlayListStrings.PL_STRING_INFO_FORMATTED_DURAT_NO_MS);
				strItem += "] " + audioDjStudio1.PlayListGetItemString(nPlayer, nCount, enumPlayListStrings.PL_STRING_INFO_TITLE);
				PlayList1.Items.Add(strItem);
			}
			PlayList1.Visible = true;
		}

		private void DisplayError(enumErrorCodes nError)
		{
			MessageBox.Show("Last operation failed due to error " + nError);
		}

		private void FormMain_Load(object sender, EventArgs e)
		{
			// load needed bitmaps into the buttons
			SetButtonsBitmaps();


			GSlider_Vol1.Value = 100;
			GSlider_Vol2.Value = 100;
			GSlider_VolMonitor.Value = 100;

			// verify presence of audio output devices
			Int32 nOutputs = audioDjStudio1.GetOutputDevicesCount();
			if (nOutputs == 0)
			{
				MessageBox.Show("No output device detected and/or connected: the program will now close. If you are running under Windows Vista or higher, jack-sensing could disable an existing sound card if no speaker is physically connected so, if you are sure that a sound card is installed, try to plug a couple of speakers into the sound card before launching again this program.");
				Close();
			}

			// display the dialog box for choosing the output device
			FormAudioOptions frmAudioOptions = new FormAudioOptions();
			frmAudioOptions.frmMain = this;
			frmAudioOptions.ShowDialog();

			// initialize the component
			audioDjStudio1.InitSoundSystem(5, m_selOutputMaster, m_selOutputMaster, m_selOutputMonitor, 0);

			// set the speakers for each player
			audioDjStudio1.StreamOutputSpeakerSet (DECKA_PLAYER, (enumSpeakers) m_selSpeakersMaster);
			audioDjStudio1.StreamOutputSpeakerSet (DECKB_PLAYER, (enumSpeakers) m_selSpeakersMaster);
			audioDjStudio1.StreamOutputSpeakerSet (PLAYLIST_PLAYER, (enumSpeakers) m_selSpeakersMonitor);
            audioDjStudio1.StreamOutputSpeakerSet(SAMPLE1_PLAYER, (enumSpeakers)m_selSpeakersMaster);
            audioDjStudio1.StreamOutputSpeakerSet(SAMPLE2_PLAYER, (enumSpeakers)m_selSpeakersMaster);

			BtnOutputMaster1.Checked = true;
			BtnOutputMaster2.Checked = true;

			timerHighRes.Enabled = true;
			timerLowRes.Enabled = true;

			// enable generating VU-Meter events passing 0 to the embedded VU meter
			audioDjStudio1.DisplayVUMeter.Create(DECKA_PLAYER, IntPtr.Zero);
			audioDjStudio1.DisplayVUMeter.Create(DECKB_PLAYER, IntPtr.Zero);
			audioDjStudio1.DisplayVUMeter.Create(PLAYLIST_PLAYER, IntPtr.Zero);

			// create a fancy VU-Meter for each player
			m_hWndVuMeterLeft[DECKA_PLAYER] = CreateVuMeter(PictureVuMeterLeft1);
			m_hWndVuMeterRight[DECKA_PLAYER] = CreateVuMeter(PictureVuMeterRight1);
			m_hWndVuMeterLeft[DECKB_PLAYER] = CreateVuMeter(PictureVuMeterLeft2);
			m_hWndVuMeterRight[DECKB_PLAYER] = CreateVuMeter(PictureVuMeterRight2);
			m_hWndVuMeterLeft[PLAYLIST_PLAYER] = CreateVuMeter(PictureVuMeterLeftMonitor);
			m_hWndVuMeterRight[PLAYLIST_PLAYER] = CreateVuMeter(PictureVuMeterRightMonitor);

			// create other visual feedbacks
			audioDjStudio1.DisplaySpectrum.Create (DECKA_PLAYER, PictureWaveform1.Handle);
			audioDjStudio1.DisplaySpectrum.Create (DECKB_PLAYER, PictureWaveform2.Handle);
			audioDjStudio1.DisplayOscilloscope.Create (DECKA_PLAYER, PictureWaveform1.Handle);
			audioDjStudio1.DisplayOscilloscope.Create (DECKB_PLAYER, PictureWaveform2.Handle);
			audioDjStudio1.DisplayWaveform.Create (DECKA_PLAYER, PictureWaveform1.Handle);
			audioDjStudio1.DisplayWaveform.Create (DECKB_PLAYER, PictureWaveform2.Handle);
		        
			audioDjStudio1.DisplayOscilloscope.set_LineWidth(DECKA_PLAYER, 2);
			audioDjStudio1.DisplayOscilloscope.set_LineWidth(DECKB_PLAYER, 2);
		    
			audioDjStudio1.DisplaySpectrum.Show (DECKA_PLAYER, true);
			audioDjStudio1.DisplaySpectrum.Show (DECKB_PLAYER, true);
			audioDjStudio1.DisplayOscilloscope.Show (DECKA_PLAYER, false);
			audioDjStudio1.DisplayOscilloscope.Show (DECKB_PLAYER, false);
			audioDjStudio1.DisplayWaveform.Show (DECKA_PLAYER, false);
			audioDjStudio1.DisplayWaveform.Show (DECKB_PLAYER, false);
		     
			OptionWaveform.Checked = true;
		             
			// create empty playlist
			audioDjStudio1.PlayListCreate (PLAYLIST_PLAYER);
		    
			// create Fader on single songs loaded
			audioDjStudio1.Fader.Init (enumFadeTypes.FADE_SINGLE, DECKA_PLAYER, DECKB_PLAYER);
			audioDjStudio1.Fader.FadeInSeekPos = -1;
		         
			// set a trigger for each player deck at 90% of the song
			enumScaleUnits	nScaleUnits = audioDjStudio1.ScaleUnits;
			audioDjStudio1.ScaleUnits = enumScaleUnits.SCALE_PERCENTAGE;
			audioDjStudio1.TriggersAdd (DECKA_PLAYER, 0, 90);
			audioDjStudio1.TriggersAdd (DECKB_PLAYER, 0, 90);
			audioDjStudio1.ScaleUnits = nScaleUnits;

			// set a granularity of 5 seconds for forward/rewind operations on all players
			audioDjStudio1.SetForwardRewindGranularity(DECKA_PLAYER, 5000);
			audioDjStudio1.SetForwardRewindGranularity(DECKB_PLAYER, 5000);
			audioDjStudio1.SetForwardRewindGranularity(PLAYLIST_PLAYER, 5000);

			m_nCurrentPosInPixels[DECKA_PLAYER] = -1;
			m_nCurrentPosInPixels[DECKB_PLAYER] = -1;
			m_nWaveformScrollStartPosInMs[DECKA_PLAYER] = 0;
			m_nWaveformScrollStartPosInMs[DECKB_PLAYER] = 0;
			m_nWaveformScrollEndPosInMs[DECKA_PLAYER] = 0;
			m_nWaveformScrollEndPosInMs[DECKB_PLAYER] = 0;

			m_bEnableRefreshWaveformFull[DECKA_PLAYER] = false;
			m_bEnableRefreshWaveformFull[DECKB_PLAYER] = false;
			m_bEnableRefreshWaveformScroll[DECKA_PLAYER] = false;
			m_bEnableRefreshWaveformScroll[DECKB_PLAYER] = false;

			// enable reversed sound creation after each LoadSound call for Player1 and Player2
			audioDjStudio1.SoundDirectionEnable (DECKA_PLAYER, true);
			audioDjStudio1.SoundDirectionEnable (DECKB_PLAYER, true);

            loadUserCode();

            this.form1.frmMain = this;
            this.form1.Show();
            this.form1.Hide();

            this.formEvents.formMain = this;

		}

		private void BtnOutputMaster1_CheckedChanged(object sender, EventArgs e)
		{
			enumErrorCodes	nError = audioDjStudio1.StreamOutputDeviceSet(DECKA_PLAYER, m_selOutputMaster);
			if (nError != enumErrorCodes.NOERROR)
				DisplayError (nError);

			// set the speakers
			audioDjStudio1.StreamOutputSpeakerSet(DECKA_PLAYER, (enumSpeakers) m_selSpeakersMaster);
		}

		private void BtnOutputMonitor1_CheckedChanged(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.StreamOutputDeviceSet(DECKA_PLAYER, m_selOutputMonitor);
			if (nError != enumErrorCodes.NOERROR)
				DisplayError(nError);

			// set the speakers
			audioDjStudio1.StreamOutputSpeakerSet(DECKA_PLAYER, (enumSpeakers) m_selSpeakersMonitor);
		}

		private void BtnOutputMaster2_CheckedChanged(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.StreamOutputDeviceSet(DECKB_PLAYER, m_selOutputMaster);
			if (nError != enumErrorCodes.NOERROR)
				DisplayError(nError);

			// set the speakers
			audioDjStudio1.StreamOutputSpeakerSet(DECKB_PLAYER, (enumSpeakers) m_selSpeakersMaster);
		}

		private void BtnOutputMonitor2_CheckedChanged(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.StreamOutputDeviceSet(DECKB_PLAYER, m_selOutputMonitor);
			if (nError != enumErrorCodes.NOERROR)
				DisplayError(nError);

			// set the speakers
			audioDjStudio1.StreamOutputSpeakerSet(DECKB_PLAYER, (enumSpeakers) m_selSpeakersMonitor);
		}

		private void GSlider_ZoomWave1_Slide(object sender, EventArgs e)
		{
			audioDjStudio1.DisplayWaveform.set_ZoomPerc(DECKA_PLAYER, (Int16) GSlider_ZoomWave1.Value);
		}

		private void GSlider_ZoomWave2_Slide(object sender, EventArgs e)
		{
			audioDjStudio1.DisplayWaveform.set_ZoomPerc(DECKB_PLAYER, (Int16) GSlider_ZoomWave2.Value);
		}

		private void BtnPlay1_Click(object sender, EventArgs e)
		{
			audioDjStudio1.SoundDirectionSet(DECKA_PLAYER, enumSoundDirections.DIRECTION_FORWARD);
    
			enumPlayerStatus	status = audioDjStudio1.GetPlayerStatus(DECKA_PLAYER);
			if (status == enumPlayerStatus.SOUND_PAUSED)
				audioDjStudio1.ResumeSound (DECKA_PLAYER);
			else if (status == enumPlayerStatus.SOUND_STOPPED)
				audioDjStudio1.PlaySound(DECKA_PLAYER);
		}

		private void BtnPlay2_Click(object sender, EventArgs e)
		{
			audioDjStudio1.SoundDirectionSet(DECKB_PLAYER, enumSoundDirections.DIRECTION_FORWARD);

			enumPlayerStatus status = audioDjStudio1.GetPlayerStatus(DECKB_PLAYER);
			if (status == enumPlayerStatus.SOUND_PAUSED)
				audioDjStudio1.ResumeSound(DECKB_PLAYER);
			else if (status == enumPlayerStatus.SOUND_STOPPED)
				audioDjStudio1.PlaySound(DECKB_PLAYER);
		}

		private void BtnPlayMonitor_Click(object sender, EventArgs e)
		{
			enumPlayerStatus status = audioDjStudio1.GetPlayerStatus(PLAYLIST_PLAYER);
			if (status == enumPlayerStatus.SOUND_PAUSED)
				audioDjStudio1.ResumeSound(PLAYLIST_PLAYER);
			else if (status == enumPlayerStatus.SOUND_PLAYING)
				return;
			else
			{
				Int16 nIndex = (Int16)PlayList1.SelectedIndex;
				if (nIndex == -1)
					nIndex = 0;

				string ItemString = audioDjStudio1.PlayListGetItemString(PLAYLIST_PLAYER, nIndex, enumPlayListStrings.PL_STRING_URL);

				audioDjStudio1.PlayListExecAt(PLAYLIST_PLAYER, nIndex);
			}
		}

		private void BtnPause1_Click(object sender, EventArgs e)
		{
			enumPlayerStatus	status = audioDjStudio1.GetPlayerStatus(DECKA_PLAYER);
			if (status == enumPlayerStatus.SOUND_PAUSED)
				audioDjStudio1.ResumeSound (DECKA_PLAYER);
			else if (status == enumPlayerStatus.SOUND_PLAYING)
				audioDjStudio1.PauseSound (DECKA_PLAYER);
		}

		private void BtnPause2_Click(object sender, EventArgs e)
		{
			enumPlayerStatus status = audioDjStudio1.GetPlayerStatus(DECKB_PLAYER);
			if (status == enumPlayerStatus.SOUND_PAUSED)
				audioDjStudio1.ResumeSound(DECKB_PLAYER);
			else if (status == enumPlayerStatus.SOUND_PLAYING)
				audioDjStudio1.PauseSound(DECKB_PLAYER);
		}

		private void BtnPauseMonitor_Click(object sender, EventArgs e)
		{
			enumPlayerStatus status = audioDjStudio1.GetPlayerStatus(PLAYLIST_PLAYER);
			if (status == enumPlayerStatus.SOUND_PAUSED)
				audioDjStudio1.ResumeSound(PLAYLIST_PLAYER);
			else if (status == enumPlayerStatus.SOUND_PLAYING)
				audioDjStudio1.PauseSound(PLAYLIST_PLAYER);
		}

		private void BtnStop1_Click(object sender, EventArgs e)
		{
			enumErrorCodes	nError = audioDjStudio1.StopSound(DECKA_PLAYER);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError (nError);
				return;
			}

			PictureWaveform1.Refresh();
		}

		private void BtnStop2_Click(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.StopSound(DECKB_PLAYER);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}

			PictureWaveform2.Refresh();
		}

		private void BtnStopMonitor_Click(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.StopSound(PLAYLIST_PLAYER);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}
		}

		private void BtnPlayRev1_Click(object sender, EventArgs e)
		{
			audioDjStudio1.SoundDirectionSet(DECKA_PLAYER, enumSoundDirections.DIRECTION_REVERSE);

			enumPlayerStatus status = audioDjStudio1.GetPlayerStatus(DECKA_PLAYER);
			if (status == enumPlayerStatus.SOUND_PAUSED)
				audioDjStudio1.ResumeSound(DECKA_PLAYER);
			else if (status == enumPlayerStatus.SOUND_STOPPED)
				audioDjStudio1.PlaySound(DECKA_PLAYER);
		}

		private void BtnPlayRev2_Click(object sender, EventArgs e)
		{
			audioDjStudio1.SoundDirectionSet(DECKB_PLAYER, enumSoundDirections.DIRECTION_REVERSE);

			enumPlayerStatus status = audioDjStudio1.GetPlayerStatus(DECKB_PLAYER);
			if (status == enumPlayerStatus.SOUND_PAUSED)
				audioDjStudio1.ResumeSound(DECKB_PLAYER);
			else if (status == enumPlayerStatus.SOUND_STOPPED)
				audioDjStudio1.PlaySound(DECKB_PLAYER);
		}

		private void BtnRewMonitor_Click(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.RewindSound(PLAYLIST_PLAYER);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}
		}

		private void BtnForwMonitor_Click(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.ForwardSound(PLAYLIST_PLAYER);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}
		}

		private void BtnPrevMonitor_Click(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.PlayListExecPrev(PLAYLIST_PLAYER);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}
		}

		private void BtnNextMonitor_Click(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.PlayListExecNext(PLAYLIST_PLAYER);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}
		}

		public void GSlider_Tempo1_Slide(object sender, EventArgs e)
		{
			float fValue = (float)GSlider_Tempo1.Value;
			enumErrorCodes nError = audioDjStudio1.SetTempoPerc(DECKA_PLAYER, fValue);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}

			LabelTempo1.Text = "Tempo: " + String.Format("{0:0.00}", fValue) + "%";
		}

		private void GSlider_Tempo1_DblClick(object sender, EventArgs e)
		{
			GSlider_Tempo1.Value = 0;
			GSlider_Tempo1_Slide(sender, e);
		}

		private void GSlider_Rate1_Slide(object sender, EventArgs e)
		{
			float fValue = (float)GSlider_Rate1.Value;
			enumErrorCodes nError = audioDjStudio1.SetRatePerc(DECKA_PLAYER, fValue);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}

			LabelRate1.Text = "Playback rate: " + String.Format("{0:0.00}", fValue) + "%";
		}

		private void GSlider_Rate1_DblClick(object sender, EventArgs e)
		{
			GSlider_Rate1.Value = 0;
			GSlider_Rate1_Slide(sender, e);
		}

		private void GSlider_Vol1_Slide(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.StreamVolumeSet(DECKA_PLAYER, (float) GSlider_Vol1.Value, enumVolumeScales.SCALE_LINEAR);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}
		}

		public void GSlider_Tempo2_Slide(object sender, EventArgs e)
		{
			float fValue = (float)GSlider_Tempo2.Value;
			enumErrorCodes nError = audioDjStudio1.SetTempoPerc(DECKB_PLAYER, fValue);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}

			LabelTempo2.Text = "Tempo: " + String.Format("{0:0.00}", fValue) + "%";
		}

		private void GSlider_Tempo2_DblClick(object sender, EventArgs e)
		{
			GSlider_Tempo2.Value = 0;
			GSlider_Tempo2_Slide(sender, e);
		}

		private void GSlider_Rate2_Slide(object sender, EventArgs e)
		{
			float fValue = (float)GSlider_Rate2.Value;
			enumErrorCodes nError = audioDjStudio1.SetRatePerc(DECKB_PLAYER, fValue);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}

			LabelRate2.Text = "Playback rate: " + String.Format("{0:0.00}", fValue) + "%";
		}

		private void GSlider_Rate2_DblClick(object sender, EventArgs e)
		{
			GSlider_Rate2.Value = 0;
			GSlider_Rate2_Slide(sender, e);
		}

		private void GSlider_Vol2_Slide(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.StreamVolumeSet(DECKB_PLAYER, (float) GSlider_Vol2.Value, enumVolumeScales.SCALE_LINEAR);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}
		}

		private void BtnStartFading_Click(object sender, EventArgs e)
		{
			enumErrorCodes nError = audioDjStudio1.Fader.StartManualFading();
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}
		}

		private void BtnFaderSetup_Click(object sender, EventArgs e)
		{
			FormFaderSetup frmFaderSetup = new FormFaderSetup();
			frmFaderSetup.frmMain = this;
			frmFaderSetup.ShowDialog();
		}

		private void BtnEqu1_Click(object sender, EventArgs e)
		{
			int	x1, y1;
			x1 = this.Left + 10;
			y1 = this.Top + this.Height - frmEqualizerA.Height;
		           
			int	x2, y2;
			x2 = this.Left + this.Width - (frmEqualizerB.Width+10);
			y2 = this.Top + this.Height - frmEqualizerB.Height;

			frmEqualizerA.Location = new Point(x1, y1);
			frmEqualizerB.Location = new Point(x2, y2);
			if (!frmEqualizerA.Visible)
			{
				frmEqualizerA.frmMain = this;
				frmEqualizerA.Show ();
				frmEqualizerB.frmMain = this;
				frmEqualizerB.Show();
			}
			else
			{
				frmEqualizerA.Hide();
				frmEqualizerB.Hide();
			}
		}

		private void BtnLoadDeckA_Click(object sender, EventArgs e)
		{
			int	nIndex = PlayList1.SelectedIndex;
			if (nIndex == -1)
			{
				MessageBox.Show ("You must select a file from the playlist below");
				return;
			}
		    
			string	strSoundFile = audioDjStudio1.PlayListGetItemString(PLAYLIST_PLAYER, (Int16) nIndex, enumPlayListStrings.PL_STRING_URL);
			audioDjStudio1.StopSound (DECKA_PLAYER);

			PictureBoxCover1.Picture = "";
			PictureBoxCover1.Hyperlink = "";
			toolTip1.SetToolTip(PictureBoxCover1, "");
			PictureBoxCover1.Cursor = Cursors.Default;

			enumErrorCodes nError = audioDjStudio1.LoadSound(DECKA_PLAYER, strSoundFile);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError (nError);
				return;
			}

			BtnInfo1.Text = audioDjStudio1.PlayListGetItemString(PLAYLIST_PLAYER, (Int16) nIndex, enumPlayListStrings.PL_STRING_INFO_TITLE);

            analizeSong(DECKA_PLAYER);
		}

		private void BtnLoadDeckB_Click(object sender, EventArgs e)
		{
			int nIndex = PlayList1.SelectedIndex;
			if (nIndex == -1)
			{
				MessageBox.Show("You must select a file from the playlist below");
				return;
			}

			string strSoundFile = audioDjStudio1.PlayListGetItemString(PLAYLIST_PLAYER, (Int16)nIndex, enumPlayListStrings.PL_STRING_URL);
			audioDjStudio1.StopSound(DECKB_PLAYER);

			PictureBoxCover2.Picture = "";
			PictureBoxCover2.Hyperlink = "";
			toolTip1.SetToolTip(PictureBoxCover2, "");
			PictureBoxCover2.Cursor = Cursors.Default;

			enumErrorCodes nError = audioDjStudio1.LoadSound(DECKB_PLAYER, strSoundFile);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}

			BtnInfo2.Text = audioDjStudio1.PlayListGetItemString(PLAYLIST_PLAYER, (Int16)nIndex, enumPlayListStrings.PL_STRING_INFO_TITLE);
		}

		private void BtnList1Load_Click(object sender, EventArgs e)
		{
			openFileDialog1.Filter = "Playlist formats (*.m3u;*.pls;*.wpl;*.pdj)|*.m3u;*.pls;*.wpl;*.pdj|M3U PlayList (*.m3u)|*.m3u|PLS PlayList (*.pls)|*.pls|WPL PlayList (*.wpl)|*.wpl|PDJ PlayList (*.pdj)|*.pdj|All files (*.*)|*.*";
			openFileDialog1.InitialDirectory = audioDjStudio1.SoundsDirectory;
			DialogResult result = openFileDialog1.ShowDialog();
			if (result == DialogResult.Cancel)
				return;

			PlayList1.Visible = false;
			ctl3dPanelPlaylist.Text = "Loading and analyzing Playlist 0%";
			ctl3dPanelPlaylist.Refresh();

			enumErrorCodes nResult = audioDjStudio1.PlayListLoadSync(PLAYLIST_PLAYER, openFileDialog1.FileName, enumPlayListModes.PLAYLIST_FULL_MODE);
			if (nResult != enumErrorCodes.NOERROR)
			{
				DisplayError (nResult);
				ctl3dPanelPlaylist.Text = "";
				PlayList1.Visible = true;
				return;
			}
		}

		private void BtnList1Save_Click(object sender, EventArgs e)
		{
			saveFileDialog1.Filter = "M3U PlayList (*.m3u)|*.m3u|PLS PlayList (*.pls)|*.pls|WPL PlayList (*.wpl)|*.wpl|PDJ PlayList (*.pdj)|*.pdj";
			saveFileDialog1.InitialDirectory = audioDjStudio1.SoundsDirectory;
			saveFileDialog1.FilterIndex = 1;
			DialogResult result = saveFileDialog1.ShowDialog();
			if (result == DialogResult.Cancel)
				return;

			if (audioDjStudio1.PlayListSave(PLAYLIST_PLAYER, saveFileDialog1.FileName, (enumPlayListFormats)(saveFileDialog1.FilterIndex - 1)) != enumErrorCodes.NOERROR)
			{
				MessageBox.Show("Error saving playlist");
				return;
			}
		}

		private void BtnAddPL1_Click(object sender, EventArgs e)
		{
			openFileDialog1.Filter =
				"Supported Sounds (*.mp3;*.mp2;*.wav;*.ogg;*.aiff;*.wma;*.wmv;*.asx;*.asf;" +
				"*.m4a;*.mp4;*.flac;*.aac;*.ac3;*.wv;" +
				"*.au;*.aif;*.w64;*.voc;*.sf;*.paf;*.pvf;*.caf;*.svx ;" +
				"*.it;*.xm;*.s3m;*.mod;*.mtm;*.mo3;*.cda)|" +
				"*.mp3;*.mp2;*.wav;*.ogg;*.aiff;*.wma;*.wmv;*.asx;*.asf;" +
				"*.m4a;*.mp4;*.flac;*.aac;*.ac3;*.wv;" +
				"*.au;*.aif;*.w64;*.voc;*.sf;*.paf;*.pvf;*.caf;*.svx ;" +
				"*.it;*.xm;*.s3m;*.mod;*.mtm;*.mo3;*.cda|" +
				"MP3 and MP2 sounds (*.mp3;*.mp2)|*.mp3;*.mp2|" +
				"AAC and MP4 sounds (*.aac;*.mp4)|*.aac;*.mp4|" +
				"WAV sounds (*.wav)|*.wav|" +
				"OGG Vorbis sounds (*.ogg)|*.ogg|" +
				"AIFF sounds (*.aiff)|*.aiff|" +
				"Windows Media sounds (*.wma;*.wmv;*.asx;*.asf)|*.wma;*.wmv;*.asx;*.asf|" +
				"AC3 sounds (*.ac3)|*.ac3;|" +
				"ALAC sounds (*.m4a)|*.ac3;|" +
				"FLAC sounds (*.flac)|*.flac;|" +
				"WavPack sounds (*.wv)|*.wv;|" +
				"MOD music (*.it;*.xm;*.s3m;*.mod;*.mtm;*.mo3)|*.it;*.xm;*.s3m;*.mod;*.mtm;*.mo3|" +
				"CD tracks (*.cda)|*.cda|" +
				"All files (*.*)|*.*";
            openFileDialog1.Multiselect = true;
			openFileDialog1.InitialDirectory = audioDjStudio1.SoundsDirectory;
			DialogResult result = openFileDialog1.ShowDialog();
			if (result != DialogResult.OK)
				return;

            foreach (string filename in openFileDialog1.FileNames)
            {
                ListBox.SelectedIndexCollection indexes = PlayList1.SelectedIndices;
                short nInsertPosition;
                if (indexes.Count > 0)
                    nInsertPosition = (short)(indexes[indexes.Count - 1] + 1);
                else
                    nInsertPosition = (short)PlayList1.Items.Count;

                enumErrorCodes nResult = audioDjStudio1.PlayListAddItem(PLAYLIST_PLAYER, filename, nInsertPosition);
                if (nResult != enumErrorCodes.NOERROR)
                {
                    DisplayError(nResult);
                    return;
                }

                PlayListAddItem(PLAYLIST_PLAYER);
                PlayList1.SelectedIndex = nInsertPosition;
            }
		}

		private void BtnEnhOptions_Click(object sender, EventArgs e)
		{
			// display the dialog box for choosing the output device

			FormAudioOptions frmAudioOptions = new FormAudioOptions();
			frmAudioOptions.frmMain = this;
			frmAudioOptions.ShowDialog();

			// set the output device
			audioDjStudio1.StreamOutputDeviceSet(DECKA_PLAYER, m_selOutputMaster);
			audioDjStudio1.StreamOutputDeviceSet(DECKB_PLAYER, m_selOutputMaster);
			audioDjStudio1.StreamOutputDeviceSet(PLAYLIST_PLAYER, m_selOutputMonitor);

			// set the speakers for each player
			audioDjStudio1.StreamOutputSpeakerSet(DECKA_PLAYER, (enumSpeakers)m_selSpeakersMaster);
			audioDjStudio1.StreamOutputSpeakerSet(DECKB_PLAYER, (enumSpeakers)m_selSpeakersMaster);
			audioDjStudio1.StreamOutputSpeakerSet(PLAYLIST_PLAYER, (enumSpeakers)m_selSpeakersMonitor);

			// update scrolling waveform views
			DrawWaveformScrolling(DECKA_PLAYER, pictureBoxWaveformScroll1);
			DrawWaveformScrolling(DECKB_PLAYER, pictureBoxWaveformScroll2);

		}

		private void BtnCredits_Click(object sender, EventArgs e)
		{
			FormCredits frmCredits = new FormCredits();
			frmCredits.ShowDialog();
		}

		private void BtnEnhInfoSel_Click(object sender, EventArgs e)
		{
			FormSoundInfo frmInfo = new FormSoundInfo();
			frmInfo.SetObject(PLAYLIST_PLAYER, PlayList1.SelectedIndex);
			frmInfo.m_frmMain = this;
			frmInfo.ShowDialog();
		}

		private void BtnRemPL1_Click(object sender, EventArgs e)
		{
			int nIndex = PlayList1.SelectedIndex;
			if (nIndex == -1)
				return;

			enumErrorCodes nError = audioDjStudio1.PlayListRemoveItem(PLAYLIST_PLAYER, (Int16)nIndex);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError (nError);
				return;
			}
		    
			PlayList1.Items.Clear();
		    
			int	nItems = audioDjStudio1.PlayListGetCount(PLAYLIST_PLAYER);
			if (nItems <= 0)
			{
				PlayList1.Visible = false;
				ctl3dPanelPlaylist.Text = "Playlist empty";
				return;
			}
		    
			for (Int16 nCount = 0; nCount < nItems; nCount++)
			{
				int nCounter = nCount + 1;
				string strItem;
				string strCounter;
				strCounter = nCounter.ToString();
				strItem = strCounter + "\t" + "[";
				strItem += audioDjStudio1.PlayListGetItemString(PLAYLIST_PLAYER, nCount, enumPlayListStrings.PL_STRING_INFO_FORMATTED_DURAT_NO_MS);
				strItem += "] " + audioDjStudio1.PlayListGetItemString(PLAYLIST_PLAYER, nCount, enumPlayListStrings.PL_STRING_INFO_TITLE);
				PlayList1.Items.Add(strItem);
			}

			if (PlayList1.SelectedIndex >= nItems)
				PlayList1.SelectedIndex = nIndex - 1;
			else
				PlayList1.SelectedIndex = nIndex;
		}

		private void GSlider_VolMonitor_Slide(object sender, EventArgs e)
		{
            //MessageBox.Show(GSlider_VolMonitor.Value.ToString());
			enumErrorCodes nError = audioDjStudio1.StreamVolumeSet(PLAYLIST_PLAYER, (float)GSlider_VolMonitor.Value, enumVolumeScales.SCALE_LINEAR);
			if (nError != enumErrorCodes.NOERROR)
			{
				DisplayError(nError);
				return;
			}
		}

		private void audioDjStudio1_BPMAvailable(object sender, BPMAvailableEventArgs e)
		{
            playerInfo[e.nPlayerIndex].bpm = e.fBPM;
			if (e.nPlayerIndex == DECKA_PLAYER)
			{
				if (e.fBPM == 0)
					LabelBPM1.Text = "BPM: Not available";
				else
					LabelBPM1.Text = "BPM: " + e.fBPM.ToString ();
			}
			else if (e.nPlayerIndex == DECKB_PLAYER)
			{
				if (e.fBPM == 0)
					LabelBPM2.Text = "BPM: Not available";
				else
					LabelBPM2.Text = "BPM: " + e.fBPM.ToString();
			}
		}

		private void audioDjStudio1_FadeInCompleted(object sender, PlayerEventArgs e)
		{
			if (e.nPlayerIndex == DECKA_PLAYER)
				GSlider_Vol1.Value = audioDjStudio1.StreamVolumeGet(e.nPlayerIndex, enumVolumeScales.SCALE_LINEAR);
			else if (e.nPlayerIndex == DECKB_PLAYER)
				GSlider_Vol2.Value = audioDjStudio1.StreamVolumeGet(e.nPlayerIndex, enumVolumeScales.SCALE_LINEAR);
		}

		private void audioDjStudio1_FadeOutCompleted(object sender, PlayerEventArgs e)
		{
			if (e.nPlayerIndex == DECKA_PLAYER)
				GSlider_Vol1.Value = audioDjStudio1.StreamVolumeGet(e.nPlayerIndex, enumVolumeScales.SCALE_LINEAR);
			else if (e.nPlayerIndex == DECKB_PLAYER)
				GSlider_Vol2.Value = audioDjStudio1.StreamVolumeGet(e.nPlayerIndex, enumVolumeScales.SCALE_LINEAR);
		}

		private void audioDjStudio1_FadingVolumeChanged(object sender, FadingEventArgs e)
		{
			if (e.nPlayerIndex == DECKA_PLAYER)
				GSlider_Vol1.Value = e.fCurrVolume;
			else if (e.nPlayerIndex == DECKB_PLAYER)
				GSlider_Vol2.Value = e.fCurrVolume;
		}

		private void audioDjStudio1_PlayListLoadPerc(object sender, PlayListLoadPercEventArgs e)
		{
			ctl3dPanelPlaylist.Text = "Loading and analyzing Playlist " + e.nPercentage.ToString () + "%";
		}

		private void audioDjStudio1_PlayListLoadDone(object sender, PlayListLoadDoneEventArgs e)
		{
			if (e.bSuccess == false)
			{
				MessageBox.Show("Error loading playlist");
				return;
			}
			int nItems = audioDjStudio1.PlayListGetCount(PLAYLIST_PLAYER);

			PlayList1.Items.Clear();

			for (Int16 nCount = 0; nCount < nItems; nCount++)
			{
				int nCounter = nCount + 1;
				string strItem;
				string strCounter;
				strCounter = nCounter.ToString();
				strItem = strCounter + "\t" + "[";
				strItem += audioDjStudio1.PlayListGetItemString(PLAYLIST_PLAYER, nCount, enumPlayListStrings.PL_STRING_INFO_FORMATTED_DURAT_NO_MS);
				strItem += "] " + audioDjStudio1.PlayListGetItemString(PLAYLIST_PLAYER, nCount, enumPlayListStrings.PL_STRING_INFO_TITLE);
				PlayList1.Items.Add(strItem);
			}
			PlayList1.SelectedIndex = 0;
			PlayList1.Visible = true;

			ctl3dPanelPlaylist.Text = "";
		}

		private void audioDjStudio1_SoundClosed(object sender, PlayerEventArgs e)
		{
			m_nCurrentPosInPixels[e.nPlayerIndex] = -1;
			if (e.nPlayerIndex == DECKA_PLAYER)
			{
				DrawWaveformFull(DECKA_PLAYER, pictureBoxWaveformFull1, m_nCurrentPosInPixels[e.nPlayerIndex]);
				DrawWaveformScrolling(DECKA_PLAYER, pictureBoxWaveformScroll1);
			}
			else if (e.nPlayerIndex == DECKB_PLAYER)
			{
				DrawWaveformFull(DECKB_PLAYER, pictureBoxWaveformFull2, m_nCurrentPosInPixels[e.nPlayerIndex]);
				DrawWaveformScrolling(DECKB_PLAYER, pictureBoxWaveformScroll2);
			}
		}

		private void audioDjStudio1_SoundDone(object sender, PlayerEventArgs e)
		{
			SmartBitmap bmpStopWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Stop_w);
			m_nCurrentPosInPixels[e.nPlayerIndex] = -1;
			if (e.nPlayerIndex == DECKA_PLAYER)
			{
				BtnInfo1.SetPictureFromHandle(Pictures.Normal, bmpStopWhite.m_hBitmap);
				BtnInfo1.TextDescrLT.Text = "  0%";
				BtnInfo1.TextDescrLT.Visible = true;
				BtnInfo1.TextDescrLT.ColorNormal = Color.LightGreen;

				DrawWaveformFull(DECKA_PLAYER, pictureBoxWaveformFull1, m_nCurrentPosInPixels[e.nPlayerIndex]);
				DrawWaveformScrolling(DECKA_PLAYER, pictureBoxWaveformScroll1);
			}
			else if (e.nPlayerIndex == DECKB_PLAYER)
			{
				BtnInfo2.SetPictureFromHandle(Pictures.Normal, bmpStopWhite.m_hBitmap);
				BtnInfo2.TextDescrLT.Text = "  0%";
				BtnInfo2.TextDescrLT.Visible = true;
				BtnInfo2.TextDescrLT.ColorNormal = Color.LightGreen;

				DrawWaveformFull(DECKB_PLAYER, pictureBoxWaveformFull2, m_nCurrentPosInPixels[e.nPlayerIndex]);
				DrawWaveformScrolling(DECKB_PLAYER, pictureBoxWaveformScroll2);
			}
		}

		private void audioDjStudio1_SoundDurationChanged(object sender, SoundDurationChangedEventArgs e)
		{
			Int32	nDurationInMillisec = (Int32) (e.fNewDuration * 1000.0f);		    
			Int32	nPositionInMillisec = audioDjStudio1.GetPlaybackTime(e.nPlayerIndex);
		    
			string	strPosition = "[" + audioDjStudio1.GetFormattedTime(nPositionInMillisec, false, true) + " of " + audioDjStudio1.GetFormattedTime(nDurationInMillisec, false, true) + "]";
			BtnInfo1.TextDescrCT.Text = strPosition;
			BtnInfo1.Refresh();

			if (e.nPlayerIndex == DECKA_PLAYER)
				BtnInfo1.TextDescrCT.Text = strPosition;
			else if (e.nPlayerIndex == DECKB_PLAYER)
				BtnInfo2.TextDescrCT.Text = strPosition;
		}

		private void CheckPictureAvailability(Int16 nPlayerIndex)
		{
			// check if there is a tag inside the file
			enumTagAvailable	nTagFormat = audioDjStudio1.TagsReader.ALL_AnalyzeSoundOnPlayer(nPlayerIndex);
			if (nTagFormat == enumTagAvailable.TAG_FLAG_NONE)
				// no known tag available inside this file
				return;
		    
			// check if the tag format allows storing pictures
			Ctl3dPictureBox	pictureBox;
			if (nPlayerIndex == DECKA_PLAYER)
				pictureBox = PictureBoxCover1;
			else
				pictureBox = PictureBoxCover2;

			bool	bHasPicture = false;
			Int32	nWidth = pictureBox.Width;
			Int32	nHeight = pictureBox.Height;
			Int32	nOriginalWidth = 0;
			Int32	nOriginalHeight = 0; 
			IntPtr	hBitmapPicture = IntPtr.Zero;
			if ((nTagFormat & enumTagAvailable.TAG_FLAG_ID3V2) != 0)
			{
				// check the availability of embedded pictures through the search of "APIC" frames
				Int32	nAvailablePictures = audioDjStudio1.TagsReader.ID3V2_FrameCountGet("APIC");
				if (nAvailablePictures > 0)
				{
					// there could be more than one picture bu we will only take the first one
					audioDjStudio1.TagsReader.ID3V2_PictureFrameBitmapGet (0, ref hBitmapPicture,
																	ref nOriginalWidth, ref nOriginalHeight, nWidth, nHeight);
					pictureBox.SetPictureFromHandle (Pictures.Normal, hBitmapPicture.ToInt32());
					bHasPicture = true;
				}
			}
			else if ((nTagFormat & enumTagAvailable.TAG_FLAG_WMA) != 0)
			{
				// check the availability of embedded pictures
				Int32	nAvailablePictures = audioDjStudio1.TagsReader.WMA_PictureFrameCountGet();
				if (nAvailablePictures > 0)
				{
					// there could be more than one picture bu we will only take the first one
					audioDjStudio1.TagsReader.WMA_PictureFrameBitmapGet(0, ref hBitmapPicture,
																	ref nOriginalWidth, ref nOriginalHeight, nWidth, nHeight);
					pictureBox.SetPictureFromHandle(Pictures.Normal, hBitmapPicture.ToInt32());
					bHasPicture = true;
				}
			}
			else if ((nTagFormat & enumTagAvailable.TAG_FLAG_MP4) != 0)
			{
				Int32	nAvailablePictures = audioDjStudio1.TagsReader.MP4_PictureFrameCountGet();
				if (nAvailablePictures > 0)
				{
					// there could be more than one picture bu we will only take the first one
					audioDjStudio1.TagsReader.MP4_PictureFrameBitmapGet(0, ref hBitmapPicture,
																	ref nOriginalWidth, ref nOriginalHeight, nWidth, nHeight);
					pictureBox.SetPictureFromHandle(Pictures.Normal, hBitmapPicture.ToInt32());
					bHasPicture = true;
				}
			}
			else if ((nTagFormat & enumTagAvailable.TAG_FLAG_FLAC) != 0)
			{
				Int32	nAvailablePictures = audioDjStudio1.TagsReader.FLAC_PictureFrameCountGet();
				if (nAvailablePictures > 0)
				{
					// there could be more than one picture bu we will only take the first one
					audioDjStudio1.TagsReader.FLAC_PictureFrameBitmapGet(0, ref hBitmapPicture,
																	ref nOriginalWidth, ref nOriginalHeight, nWidth, nHeight);
					pictureBox.SetPictureFromHandle(Pictures.Normal, hBitmapPicture.ToInt32());
					bHasPicture = true;
				}
			}

			// check if a CD containing this song is available on the Amazon store
			enumErrorCodes nResult = audioDjStudio1.AmazonStoreCdInfoCreate(nPlayerIndex, "");
			if (nResult != enumErrorCodes.NOERROR)
				// not available
				return;

			// add the hyperlink to the picture control
			pictureBox.Hyperlink = audioDjStudio1.AmazonStoreCdInfoGet(nPlayerIndex, enumAmazonStoreInfo.AMAZON_STORE_CD_URL_PURCHASE);
			toolTip1.SetToolTip (pictureBox, "Click the picture to navigate to the CD purchase page on Amazon");
			pictureBox.Cursor = Cursors.Hand;
		    
			// check if we already have a picture inside the tag to display
			if (!bHasPicture)
				// no picture inside the tag, use the one from Amazon store
				pictureBox.Picture = audioDjStudio1.AmazonStoreCdCoverPictureFileGet(nPlayerIndex, enumCdCoverSizes.CD_COVER_SIZE_MEDIUM);
		}

		private void audioDjStudio1_SoundLoaded(object sender, SoundLoadedEventArgs e)
		{
			Int32	nDurationInMillisec = audioDjStudio1.GetSoundDuration(e.nPlayerIndex);
			string	strPosition = "[00:00.000 of " + audioDjStudio1.GetFormattedTime(nDurationInMillisec, false, true) + "]";
		       
			if (e.nPlayerIndex == DECKA_PLAYER)
			{
				BtnInfo1.TextDescrLT.Text = "  0%";
				BtnInfo1.TextDescrCT.Text = strPosition;

				// perform waveform analysis
				audioDjStudio1.DisplayWaveform.AnalyzeFullSound(DECKA_PLAYER, enumWaveformResolutions.WAVEFORM_RES_LOW);

				// check if a picture cover is available for this file
				CheckPictureAvailability(e.nPlayerIndex);
			}
			else if (e.nPlayerIndex == DECKB_PLAYER)
			{
				BtnInfo2.TextDescrLT.Text = "  0%";
				BtnInfo2.TextDescrCT.Text = strPosition;

				// perform waveform analysis
				audioDjStudio1.DisplayWaveform.AnalyzeFullSound(DECKB_PLAYER, enumWaveformResolutions.WAVEFORM_RES_LOW);

				// check if a picture cover is available for this file
				CheckPictureAvailability(e.nPlayerIndex);
			}
			else if (e.nPlayerIndex == PLAYLIST_PLAYER)
				// select the new item
				PlayList1.SelectedIndex = e.nItemIndex;            
		}

		private void audioDjStudio1_SoundPaused(object sender, PlayerEventArgs e)
		{
			SmartBitmap bmpPauseWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Pause_w);
			if (e.nPlayerIndex == DECKA_PLAYER)
				BtnInfo1.SetPictureFromHandle(Pictures.Normal, bmpPauseWhite.m_hBitmap);
			else if (e.nPlayerIndex == DECKB_PLAYER)
				BtnInfo2.SetPictureFromHandle(Pictures.Normal, bmpPauseWhite.m_hBitmap);
		}

		private void audioDjStudio1_SoundPlaying(object sender, PlayerEventArgs e)
		{
			SmartBitmap bmpPlayWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Play_w);
			if (e.nPlayerIndex == DECKA_PLAYER)
			{
				BtnInfo1.SetPictureFromHandle(Pictures.Normal, bmpPlayWhite.m_hBitmap);
				BtnInfo1.TextDescrLT.Visible = true;
			}
			else if (e.nPlayerIndex == DECKB_PLAYER)
			{
				BtnInfo2.SetPictureFromHandle(Pictures.Normal, bmpPlayWhite.m_hBitmap);
				BtnInfo2.TextDescrLT.Visible = true;
			}
		}

		private void audioDjStudio1_SoundStopped(object sender, PlayerEventArgs e)
		{
			SmartBitmap bmpStopWhite = new SmartBitmap(IntelliTouchMix.Properties.Resources.Stop_w);
            //MessageBox.Show(e.nPlayerIndex.ToString());
			m_nCurrentPosInPixels[e.nPlayerIndex] = -1;
			if (e.nPlayerIndex == DECKA_PLAYER)
			{
				BtnInfo1.SetPictureFromHandle(Pictures.Normal, bmpStopWhite.m_hBitmap);
				BtnInfo1.TextDescrLT.Visible = true;
		        BtnInfo1.TextDescrLT.Text = "  0%";
				BtnInfo1.TextDescrLT.ColorNormal = Color.LightGreen;

				DrawWaveformFull(DECKA_PLAYER, pictureBoxWaveformFull1, m_nCurrentPosInPixels[e.nPlayerIndex]);
				DrawWaveformScrolling(DECKA_PLAYER, pictureBoxWaveformScroll1);
			}
			else if (e.nPlayerIndex == DECKB_PLAYER)
			{
				BtnInfo2.SetPictureFromHandle(Pictures.Normal, bmpStopWhite.m_hBitmap);
				BtnInfo2.TextDescrLT.Visible = true;
				BtnInfo2.TextDescrLT.Text = "  0%";
				BtnInfo2.TextDescrLT.ColorNormal = Color.LightGreen;

				DrawWaveformFull(DECKB_PLAYER, pictureBoxWaveformFull2, m_nCurrentPosInPixels[e.nPlayerIndex]);
				DrawWaveformScrolling(DECKB_PLAYER, pictureBoxWaveformScroll2);
			}
		}

		private void audioDjStudio1_TriggerReached(object sender, TriggerReachedEventArgs e)
		{
			if (e.nPlayerIndex == DECKA_PLAYER)
				BtnInfo1.TextDescrLT.ColorNormal = Color.Red;
			else if (e.nPlayerIndex == DECKB_PLAYER)
				BtnInfo2.TextDescrLT.ColorNormal = Color.Red;
		}

		private void audioDjStudio1_VUMeterValueChange(object sender, VUMeterValueChangeEventArgs e)
		{
			// update VU-meters
			audioDjStudio1.GraphicBarsManager.SetValue(m_hWndVuMeterLeft[e.nPlayerIndex], e.nPeakLeft);
			audioDjStudio1.GraphicBarsManager.SetValue(m_hWndVuMeterRight[e.nPlayerIndex], e.nPeakRight);
		}

		private void audioDjStudio1_WaveAnalysisDone(object sender, WaveAnalysisDoneEventArgs e)
		{
			if (e.nTotalPeaksDetected == 0)
				// the analysis was probably interrupted
				return;

			m_nTotalWavePeaks[e.nPlayerIndex] = e.nTotalPeaksDetected;
			m_fPeakDurationInMs[e.nPlayerIndex] = e.fPeakDurationInMs;
			switch (e.nPlayerIndex)
			{
			case 0:		// PLAYER1
				timerDisplayWaveform1.Enabled = true;
				break;
			case 1:		// PLAYER2
				timerDisplayWaveform2.Enabled = true;
				break;
			}
		}

		private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
		{
			frmEqualizerA.Close();
			frmEqualizerB.Close();

			audioDjStudio1.CloseSound(DECKA_PLAYER);
			audioDjStudio1.CloseSound(DECKB_PLAYER);
			audioDjStudio1.CloseSound(PLAYLIST_PLAYER);

			Hide();
            Dispose();
            //Close();
			//FormWarn3D frmWarn = new FormWarn3D();
			//frmWarn.ShowDialog();
		}

		private void OptionWaveform_CheckedChanged(object sender, EventArgs e)
		{
			audioDjStudio1.DisplaySpectrum.Show (DECKA_PLAYER, false);
			audioDjStudio1.DisplaySpectrum.Show (DECKB_PLAYER, false);
			audioDjStudio1.DisplayOscilloscope.Show (DECKA_PLAYER, false);
			audioDjStudio1.DisplayOscilloscope.Show (DECKB_PLAYER, false);
			audioDjStudio1.DisplayWaveform.Show (DECKA_PLAYER, true);
			audioDjStudio1.DisplayWaveform.Show (DECKB_PLAYER, true);
		    
			GSlider_ZoomWave1.Visible = true;
			GSlider_ZoomWave2.Visible = true;
		}

		private void OptionSpectrum_CheckedChanged(object sender, EventArgs e)
		{
			audioDjStudio1.DisplaySpectrum.Show(DECKA_PLAYER, true);
			audioDjStudio1.DisplaySpectrum.Show(DECKB_PLAYER, true);
			audioDjStudio1.DisplayOscilloscope.Show(DECKA_PLAYER, false);
			audioDjStudio1.DisplayOscilloscope.Show(DECKB_PLAYER, false);
			audioDjStudio1.DisplayWaveform.Show(DECKA_PLAYER, false);
			audioDjStudio1.DisplayWaveform.Show(DECKB_PLAYER, false);

			GSlider_ZoomWave1.Visible = false;
			GSlider_ZoomWave2.Visible = false;
		}

		private void OptionOscill_CheckedChanged(object sender, EventArgs e)
		{
			audioDjStudio1.DisplaySpectrum.Show(DECKA_PLAYER, false);
			audioDjStudio1.DisplaySpectrum.Show(DECKB_PLAYER, false);
			audioDjStudio1.DisplayOscilloscope.Show(DECKA_PLAYER, true);
			audioDjStudio1.DisplayOscilloscope.Show(DECKB_PLAYER, true);
			audioDjStudio1.DisplayWaveform.Show(DECKA_PLAYER, false);
			audioDjStudio1.DisplayWaveform.Show(DECKB_PLAYER, false);

			GSlider_ZoomWave1.Visible = false;
			GSlider_ZoomWave2.Visible = false;
		}

		private void PlayList1_DoubleClick(object sender, EventArgs e)
		{
			int	nIndex = PlayList1.SelectedIndex;
			if (nIndex == -1)
				return;

			string	ItemString = audioDjStudio1.PlayListGetItemString(PLAYLIST_PLAYER, (Int16) nIndex, enumPlayListStrings.PL_STRING_URL);
			audioDjStudio1.PlayListExecAt(PLAYLIST_PLAYER, (Int16)nIndex);
		}

		private void timerHighRes_Tick(object sender, EventArgs e)
		{
			enumPlayerStatus status1 = audioDjStudio1.GetPlayerStatus(DECKA_PLAYER);
			enumPlayerStatus status2 = audioDjStudio1.GetPlayerStatus(DECKB_PLAYER);
		    
			int nDurationInMillisec;
			int nPositionInMillisec;
			string strPosition;

			if (status1 != enumPlayerStatus.SOUND_NONE)
			{
				nPositionInMillisec = audioDjStudio1.GetPlaybackTime(DECKA_PLAYER);
				nDurationInMillisec = audioDjStudio1.GetSoundDuration(DECKA_PLAYER);
				strPosition = "[" + audioDjStudio1.GetFormattedTime(nPositionInMillisec, false, true) + " of " + audioDjStudio1.GetFormattedTime(nDurationInMillisec, false, true) + "]";
				BtnInfo1.TextDescrCT.Text = strPosition;
				BtnInfo1.Refresh();
			}

			if (status2 != enumPlayerStatus.SOUND_NONE)
			{
				nPositionInMillisec = audioDjStudio1.GetPlaybackTime(DECKB_PLAYER);
				nDurationInMillisec = audioDjStudio1.GetSoundDuration(DECKB_PLAYER);
				strPosition = "[" + audioDjStudio1.GetFormattedTime(nPositionInMillisec, false, true) + " of " + audioDjStudio1.GetFormattedTime(nDurationInMillisec, false, true) + "]";
				BtnInfo2.TextDescrCT.Text = strPosition;
				BtnInfo2.Refresh();
			}

			//*************************************
			// draw the scrolling waveform
			if (status1 == enumPlayerStatus.SOUND_PLAYING)
				DrawWaveformScrolling(DECKA_PLAYER, pictureBoxWaveformScroll1);
			if (status2 == enumPlayerStatus.SOUND_PLAYING)
				DrawWaveformScrolling(DECKB_PLAYER, pictureBoxWaveformScroll2);

			int	nIndex = PlayList1.SelectedIndex;
			if (nIndex == -1)
			{
				BtnLoadDeckA.Enabled = false;
				BtnLoadDeckB.Enabled = false;
				BtnEnhInfoSel.Enabled = false;
				BtnRemPL1.Enabled = false;
			}
			else
			{
				BtnLoadDeckA.Enabled = true;
				BtnLoadDeckB.Enabled = true;
				BtnEnhInfoSel.Enabled = true;
				BtnRemPL1.Enabled = true;
			}
		}

		private void timerLowRes_Tick(object sender, EventArgs e)
		{
			enumPlayerStatus status1 = audioDjStudio1.GetPlayerStatus(DECKA_PLAYER);
			if (status1 == enumPlayerStatus.SOUND_PAUSED)
				BtnInfo1.TextDescrLT.Visible = !BtnInfo1.TextDescrLT.Visible;

			enumPlayerStatus status2 = audioDjStudio1.GetPlayerStatus(DECKB_PLAYER);
			if (status2 == enumPlayerStatus.SOUND_PAUSED)
				BtnInfo2.TextDescrLT.Visible = !BtnInfo2.TextDescrLT.Visible;

			enumScaleUnits nScaleUnits = audioDjStudio1.ScaleUnits;
			audioDjStudio1.ScaleUnits = enumScaleUnits.SCALE_PERCENTAGE;
			if (status1 != enumPlayerStatus.SOUND_NONE)
			{
				int nPerc = audioDjStudio1.GetCurrentPos(DECKA_PLAYER);
				if (nPerc < 0)
					nPerc = 0;
				BtnInfo1.TextDescrLT.Text = "  " + nPerc.ToString() + "%";
			}

			if (status2 != enumPlayerStatus.SOUND_NONE)
			{
				int nPerc = audioDjStudio1.GetCurrentPos(DECKB_PLAYER);
				if (nPerc < 0)
					nPerc = 0;
				BtnInfo2.TextDescrLT.Text = "  " + nPerc.ToString() + "%";
			}

			//*************************************
			// draw the current position white line
			audioDjStudio1.ScaleUnits = enumScaleUnits.SCALE_MILLISECONDS;

			if (status1 == enumPlayerStatus.SOUND_PLAYING || m_bEnableRefreshWaveformFull[DECKA_PLAYER])
			{
				// port the position on the bitmap
				Int32	nViewWidthInPixels = pictureBoxWaveformFull1.Width;
				Int32	nViewWidthInMs = audioDjStudio1.GetSoundDuration(DECKA_PLAYER);
				float	fPixelDurationInMs = (float) nViewWidthInMs / (float) nViewWidthInPixels;
				m_nCurrentPosInPixels[DECKA_PLAYER] = (Int32)(audioDjStudio1.GetPlaybackTime(DECKA_PLAYER) / fPixelDurationInMs);
				DrawWaveformFull(DECKA_PLAYER, pictureBoxWaveformFull1, m_nCurrentPosInPixels[DECKA_PLAYER]);
			}
			if (m_bEnableRefreshWaveformScroll[DECKA_PLAYER])
				DrawWaveformScrolling(DECKA_PLAYER, pictureBoxWaveformScroll1);

			if (status2 == enumPlayerStatus.SOUND_PLAYING || m_bEnableRefreshWaveformFull[DECKB_PLAYER])
			{
				// port the position on the bitmap
				Int32 nViewWidthInPixels = pictureBoxWaveformFull2.Width;
				Int32 nViewWidthInMs = audioDjStudio1.GetSoundDuration(DECKB_PLAYER);
				float fPixelDurationInMs = (float)nViewWidthInMs / (float)nViewWidthInPixels;
				m_nCurrentPosInPixels[DECKB_PLAYER] = (Int32)(audioDjStudio1.GetPlaybackTime(DECKB_PLAYER) / fPixelDurationInMs);
				DrawWaveformFull(DECKB_PLAYER, pictureBoxWaveformFull2, m_nCurrentPosInPixels[DECKB_PLAYER]);
			}
			if (m_bEnableRefreshWaveformScroll[DECKB_PLAYER])
				DrawWaveformScrolling(DECKB_PLAYER, pictureBoxWaveformScroll2);

			audioDjStudio1.ScaleUnits = nScaleUnits;
		}

		private void FormMain_Click(object sender, EventArgs e)
		{
			if (frmEqualizerA.Visible)
				BtnEqu1_Click(sender, e);
		}

		private void BtnAboutDj_Click(object sender, EventArgs e)
		{
			audioDjStudio1.AboutBox();
		}

		private void BtnAbout3d_Click(object sender, EventArgs e)
		{
			BtnInfo1.AboutBox();
		}

		private void timerDisplayWaveform1_Tick(object sender, EventArgs e)
		{
			timerDisplayWaveform1.Enabled = false;
		    
			// draw the full waveform
			DrawWaveformFull(DECKA_PLAYER, pictureBoxWaveformFull1, m_nCurrentPosInPixels[DECKA_PLAYER]);

			// draw the scrolling waveform
			DrawWaveformScrolling(DECKA_PLAYER, pictureBoxWaveformScroll1);
		}

		private void timerDisplayWaveform2_Tick(object sender, EventArgs e)
		{
			timerDisplayWaveform2.Enabled = false;

			// draw the full waveform
			DrawWaveformFull(DECKB_PLAYER, pictureBoxWaveformFull2, m_nCurrentPosInPixels[DECKB_PLAYER]);

			// draw the scrolling waveform
			DrawWaveformScrolling(DECKB_PLAYER, pictureBoxWaveformScroll2);
		}

		private void ManageMouseDownOnScroll(Int16 nPlayerIndex, MouseEventArgs e)
		{
			if (e.Button != MouseButtons.Left && e.Button != MouseButtons.Right)
				return;

			enumPlayerStatus	status = audioDjStudio1.GetPlayerStatus(nPlayerIndex);
			if (status == enumPlayerStatus.SOUND_PLAYING)
			{
				audioDjStudio1.PauseSound (nPlayerIndex);
				m_bMustResumeOnMouseUp[nPlayerIndex] = true;
			}
			else
				m_bMustResumeOnMouseUp[nPlayerIndex] = false;

			enumScaleUnits nScaleUnits = audioDjStudio1.ScaleUnits;
			audioDjStudio1.ScaleUnits = enumScaleUnits.SCALE_MILLISECONDS;

			PictureBox pictureBoxWaveformScroll;
			PictureBox pictureBoxWaveformFull;
			if (nPlayerIndex == DECKA_PLAYER)
			{
				pictureBoxWaveformScroll = pictureBoxWaveformScroll1;
				pictureBoxWaveformFull = pictureBoxWaveformFull1;
			}
			else
			{
				pictureBoxWaveformScroll = pictureBoxWaveformScroll2;
				pictureBoxWaveformFull = pictureBoxWaveformFull2;
			}

			// determine the position of the click from pixels to ms
			Int32	nViewWidthInPixels = pictureBoxWaveformScroll.Width;
			Int32	nViewWidthInMs = m_nWaveformScrollEndPosInMs[nPlayerIndex] - m_nWaveformScrollStartPosInMs[nPlayerIndex];
		   
			float	fPixelDurationInMs = (float) nViewWidthInMs / (float) nViewWidthInPixels;
		    
			m_nPixelPositionOnWaveform[nPlayerIndex] = e.X;

			if (e.Button == MouseButtons.Right)
			{
				Int32 nPositionToSeekInMs = m_nWaveformScrollStartPosInMs[nPlayerIndex] + (Int32)((float)m_nPixelPositionOnWaveform[nPlayerIndex] * fPixelDurationInMs);
				if (nPositionToSeekInMs < 0)
					nPositionToSeekInMs = 0;

				// move the current playback position
				audioDjStudio1.SeekSound(nPlayerIndex, (UInt32) nPositionToSeekInMs);

				// update scrolling waveform
				DrawWaveformScrolling(nPlayerIndex, pictureBoxWaveformScroll);

				// update full waveform
				float fPixelDurationOnFullInMs = audioDjStudio1.GetSoundDuration(nPlayerIndex) / pictureBoxWaveformFull.Width;
				m_nCurrentPosInPixels[nPlayerIndex] = (Int32)((float)audioDjStudio1.GetPlaybackTime(nPlayerIndex) / fPixelDurationOnFullInMs);
				DrawWaveformFull(nPlayerIndex, pictureBoxWaveformFull, m_nCurrentPosInPixels[nPlayerIndex]);
			}
			audioDjStudio1.ScaleUnits = nScaleUnits;
		}

        

		private void ManageMouseMoveOnScroll(Int16 nPlayerIndex, MouseEventArgs e)
		{
			if (e.Button != MouseButtons.Left)
				return;
		    
			enumPlayerStatus	status = audioDjStudio1.GetPlayerStatus(nPlayerIndex);
			if (status != enumPlayerStatus.SOUND_PAUSED && status != enumPlayerStatus.SOUND_STOPPED)
				return;

			enumScaleUnits nScaleUnits = audioDjStudio1.ScaleUnits;
			audioDjStudio1.ScaleUnits = enumScaleUnits.SCALE_MILLISECONDS;

			PictureBox pictureBoxWaveformScroll;
			PictureBox pictureBoxWaveformFull;
			if (nPlayerIndex == DECKA_PLAYER)
			{
				pictureBoxWaveformScroll = pictureBoxWaveformScroll1;
				pictureBoxWaveformFull = pictureBoxWaveformFull1;
			}
			else
			{
				pictureBoxWaveformScroll = pictureBoxWaveformScroll2;
				pictureBoxWaveformFull = pictureBoxWaveformFull2;
			}

			// determine the position of the click from pixels to ms
			Int32	nViewWidthInPixels = pictureBoxWaveformScroll.Width;
			Int32	nViewWidthInMs = m_nWaveformScrollEndPosInMs[nPlayerIndex] - m_nWaveformScrollStartPosInMs[nPlayerIndex];
		   
			float	fPixelDurationInMs = (float) nViewWidthInMs / (float) nViewWidthInPixels;
		    
			Int32	nPixelPosition = e.X;
		    
			// check if must scroll left or right
			Int32	nPixelsToScroll;
			if (nPixelPosition < m_nPixelPositionOnWaveform[nPlayerIndex])
				// scroll left
				nPixelsToScroll = (m_nPixelPositionOnWaveform[nPlayerIndex] - nPixelPosition);
			else
				// scroll right
				nPixelsToScroll = -(nPixelPosition - m_nPixelPositionOnWaveform[nPlayerIndex]);
		    
			// remember the last mouse position
			m_nPixelPositionOnWaveform[nPlayerIndex] = nPixelPosition;
		    
			// calculate the new position
			Int32	nPosDifferenceInMs = (Int32)((float) nPixelsToScroll * fPixelDurationInMs);
			Int32	nNewPosInMs = audioDjStudio1.GetPlaybackTime(nPlayerIndex) + nPosDifferenceInMs;
		    
			// check limits
			if (nNewPosInMs < 0)
				nNewPosInMs = 0;
			else if (nNewPosInMs > audioDjStudio1.GetSoundDuration(nPlayerIndex))
				nNewPosInMs = audioDjStudio1.GetSoundDuration(nPlayerIndex);
		        
			// move the current playback position
			audioDjStudio1.SeekSound (nPlayerIndex, (UInt32) nNewPosInMs);

		    // update scrolling waveform
			DrawWaveformScrolling(nPlayerIndex, pictureBoxWaveformScroll);

			// update full waveform
			float	fPixelDurationOnFullInMs = audioDjStudio1.GetSoundDuration(nPlayerIndex) / pictureBoxWaveformFull.Width;
			m_nCurrentPosInPixels[nPlayerIndex] = (Int32)((float) audioDjStudio1.GetPlaybackTime(nPlayerIndex) / fPixelDurationOnFullInMs);
			DrawWaveformFull(nPlayerIndex, pictureBoxWaveformFull, m_nCurrentPosInPixels[nPlayerIndex]);

			audioDjStudio1.ScaleUnits = nScaleUnits;
		}

        private void ManageTouchMoveOnScroll(Int16 nPlayerIndex, TouchMouseEventArgs e)
        {
                               
            enumPlayerStatus status = audioDjStudio1.GetPlayerStatus(nPlayerIndex);
            if (status != enumPlayerStatus.SOUND_PAUSED && status != enumPlayerStatus.SOUND_STOPPED)
                return;

            enumScaleUnits nScaleUnits = audioDjStudio1.ScaleUnits;
            audioDjStudio1.ScaleUnits = enumScaleUnits.SCALE_MILLISECONDS;

            PictureBox pictureBoxWaveformScroll;
            PictureBox pictureBoxWaveformFull;
            if (nPlayerIndex == DECKA_PLAYER)
            {
                pictureBoxWaveformScroll = pictureBoxWaveformScroll1;
                pictureBoxWaveformFull = pictureBoxWaveformFull1;
            }
            else
            {
                pictureBoxWaveformScroll = pictureBoxWaveformScroll2;
                pictureBoxWaveformFull = pictureBoxWaveformFull2;
            }

            // determine the position of the click from pixels to ms
            Int32 nViewWidthInPixels = pictureBoxWaveformScroll.Width;
            Int32 nViewWidthInMs = m_nWaveformScrollEndPosInMs[nPlayerIndex] - m_nWaveformScrollStartPosInMs[nPlayerIndex];

            float fPixelDurationInMs = (float)nViewWidthInMs / (float)nViewWidthInPixels;

            Int32 nPixelPosition = (Int32)e.distance;

            // check if must scroll left or right
            Int32 nPixelsToScroll;
            if (nPixelPosition < m_nPixelPositionOnWaveform[nPlayerIndex])
                // scroll left
                nPixelsToScroll = (m_nPixelPositionOnWaveform[nPlayerIndex] - nPixelPosition);
            else
                // scroll right
                nPixelsToScroll = -(nPixelPosition - m_nPixelPositionOnWaveform[nPlayerIndex]);

            // remember the last mouse position
            m_nPixelPositionOnWaveform[nPlayerIndex] = nPixelPosition;

            // calculate the new position
            Int32 nPosDifferenceInMs = (Int32)((float)nPixelsToScroll * fPixelDurationInMs);
            Int32 nNewPosInMs = audioDjStudio1.GetPlaybackTime(nPlayerIndex) + nPosDifferenceInMs;

            // check limits
            if (nNewPosInMs < 0)
                nNewPosInMs = 0;
            else if (nNewPosInMs > audioDjStudio1.GetSoundDuration(nPlayerIndex))
                nNewPosInMs = audioDjStudio1.GetSoundDuration(nPlayerIndex);

            // move the current playback position
            audioDjStudio1.SeekSound(nPlayerIndex, (UInt32)nNewPosInMs);

            // update scrolling waveform
            DrawWaveformScrolling(nPlayerIndex, pictureBoxWaveformScroll);

            // update full waveform
            float fPixelDurationOnFullInMs = audioDjStudio1.GetSoundDuration(nPlayerIndex) / pictureBoxWaveformFull.Width;
            m_nCurrentPosInPixels[nPlayerIndex] = (Int32)((float)audioDjStudio1.GetPlaybackTime(nPlayerIndex) / fPixelDurationOnFullInMs);
            DrawWaveformFull(nPlayerIndex, pictureBoxWaveformFull, m_nCurrentPosInPixels[nPlayerIndex]);

            audioDjStudio1.ScaleUnits = nScaleUnits;
        }


		private void ManageMouseUpOnScroll(Int16 nPlayerIndex, MouseEventArgs e)
		{
			if (e.Button != MouseButtons.Left && e.Button != MouseButtons.Right)
				return;
		        
			// check if need to resume playback after seeking
			if (m_bMustResumeOnMouseUp[nPlayerIndex])
				audioDjStudio1.ResumeSound (nPlayerIndex);
		}

		private void pictureBoxWaveformScroll1_MouseDown(object sender, MouseEventArgs e)
		{
			ManageMouseDownOnScroll(DECKA_PLAYER, e);
		}

		private void pictureBoxWaveformScroll1_MouseMove(object sender, MouseEventArgs e)
		{
			ManageMouseMoveOnScroll(DECKA_PLAYER, e);
		}

		private void pictureBoxWaveformScroll1_MouseUp(object sender, MouseEventArgs e)
		{
			ManageMouseUpOnScroll(DECKA_PLAYER, e);
		}

		private void pictureBoxWaveformScroll2_MouseDown(object sender, MouseEventArgs e)
		{
			ManageMouseDownOnScroll(DECKB_PLAYER, e);
		}

		private void pictureBoxWaveformScroll2_MouseMove(object sender, MouseEventArgs e)
		{
			ManageMouseMoveOnScroll(DECKB_PLAYER, e);
		}

		private void pictureBoxWaveformScroll2_MouseUp(object sender, MouseEventArgs e)
		{
			ManageMouseUpOnScroll(DECKB_PLAYER, e);
		}

		private void ManageMouseUpOnFull(Int16 nPlayerIndex, MouseEventArgs e)
		{
			enumScaleUnits nScaleUnits = audioDjStudio1.ScaleUnits;
			audioDjStudio1.ScaleUnits = enumScaleUnits.SCALE_MILLISECONDS;

			PictureBox pictureBoxWaveformScroll;
			PictureBox pictureBoxWaveformFull;
			if (nPlayerIndex == DECKA_PLAYER)
			{
				pictureBoxWaveformScroll = pictureBoxWaveformScroll1;
				pictureBoxWaveformFull = pictureBoxWaveformFull1;
			}
			else
			{
				pictureBoxWaveformScroll = pictureBoxWaveformScroll2;
				pictureBoxWaveformFull = pictureBoxWaveformFull2;
			}

			// determine the position of the click from pixels to ms
			Int32 nViewWidthInPixels = pictureBoxWaveformScroll.Width;
			Int32 nViewWidthInMs = audioDjStudio1.GetSoundDuration (nPlayerIndex);

			float fPixelDurationInMs = (float)nViewWidthInMs / (float)nViewWidthInPixels;

			Int32	nPixelPositionOnWaveform = e.X;

			Int32 nPositionToSeekInMs = (Int32)((float) nPixelPositionOnWaveform * fPixelDurationInMs);

			// move the current playback position
			audioDjStudio1.SeekSound(nPlayerIndex, (UInt32)nPositionToSeekInMs);

			// update scrolling waveform
			DrawWaveformScrolling(nPlayerIndex, pictureBoxWaveformScroll);

			// update full waveform
			float fPixelDurationOnFullInMs = audioDjStudio1.GetSoundDuration(nPlayerIndex) / pictureBoxWaveformFull.Width;
			m_nCurrentPosInPixels[nPlayerIndex] = (Int32)((float)audioDjStudio1.GetPlaybackTime(nPlayerIndex) / fPixelDurationOnFullInMs);
			DrawWaveformFull(nPlayerIndex, pictureBoxWaveformFull, m_nCurrentPosInPixels[nPlayerIndex]);

			audioDjStudio1.ScaleUnits = nScaleUnits;
		}

		private void pictureBoxWaveformFull1_MouseUp(object sender, MouseEventArgs e)
		{
			ManageMouseUpOnFull(DECKA_PLAYER, e);
		}

		private void pictureBoxWaveformFull2_MouseUp(object sender, MouseEventArgs e)
		{
			ManageMouseUpOnFull(DECKB_PLAYER, e);
		}

		private void pictureBoxWaveformFull1_Paint(object sender, PaintEventArgs e)
		{
			m_bEnableRefreshWaveformFull[DECKA_PLAYER] = true;
		}

		private void pictureBoxWaveformFull2_Paint(object sender, PaintEventArgs e)
		{
			m_bEnableRefreshWaveformFull[DECKB_PLAYER] = true;
		}

		private void pictureBoxWaveformScroll1_Paint(object sender, PaintEventArgs e)
		{
			m_bEnableRefreshWaveformScroll[DECKA_PLAYER] = true;
		}

		private void pictureBoxWaveformScroll2_Paint(object sender, PaintEventArgs e)
		{
			m_bEnableRefreshWaveformScroll[DECKB_PLAYER] = true;
		}

		private void BtnCueRec1_Click(object sender, EventArgs e)
		{
			BtnCueDel1.Checked = false;
		}

		private void BtnCueRec2_Click(object sender, EventArgs e)
		{
			BtnCueDel2.Checked = false;
		}

		private void BtnCueDel1_Click(object sender, EventArgs e)
		{
			BtnCueRec1.Checked = false;
		}

		private void BtnCueDel2_Click(object sender, EventArgs e)
		{
			BtnCueRec2.Checked = false;
		}

		private void ManageCuePoint(Int16 nPlayerIndex, string strCuePointName, Int16 nVerticalLineID, Ctl3dPushButton btnCue,
			Ctl3dCheckBox btnRec, Ctl3dCheckBox btnDel)
		{
			Int32	nCuePointPos;
			if (btnRec.Checked)
			{
				// record cue point
				nCuePointPos = audioDjStudio1.GetCurrentPos(nPlayerIndex);
		        
				enumErrorCodes	err = audioDjStudio1.CuePointsAdd(nPlayerIndex, strCuePointName, nCuePointPos);
				if (err == enumErrorCodes.ERR_ALREADY_EXISTS)
				{
					// the cue point already exists, change its position
					audioDjStudio1.CuePointsSetPos (nPlayerIndex, strCuePointName, nCuePointPos);
					audioDjStudio1.DisplayWaveform.BitmapViewVerticalLineRemove (nPlayerIndex, nVerticalLineID);
				}
		        
				// add a vertical line to the waveform on the corresponding position
				audioDjStudio1.DisplayWaveform.BitmapViewVerticalLineAdd (nPlayerIndex, nVerticalLineID, nCuePointPos,
																			Color.OrangeRed, enumWaveformLineModes.LINE_MODE_SOLID, 2);

				// change the color of the button's text to red so we know that this cue point is set
				btnCue.ForeColor = Color.Red;
		        
				btnRec.Checked = false;
			}
			else if (btnDel.Checked)
			{
				// remove cue point
				audioDjStudio1.CuePointsRemove (nPlayerIndex, strCuePointName);
		        
				// remove corresponding vertical line
				audioDjStudio1.DisplayWaveform.BitmapViewVerticalLineRemove (nPlayerIndex, nVerticalLineID);
		        
				// change the color of the button's text to white so we know that this cue point is reset
				btnCue.ForeColor = Color.White;
		        
				btnDel.Checked = false;		    
			}
			else
			{
				// seek to cue point position
				nCuePointPos = audioDjStudio1.CuePointsGetPos(nPlayerIndex, strCuePointName);
				if (nCuePointPos < 0)
					nCuePointPos = 0;

				audioDjStudio1.SeekSound(nPlayerIndex, (UInt32) nCuePointPos);
			}

			// refresh waveforms
			if (nPlayerIndex == DECKA_PLAYER)
			{
				DrawWaveformFull(DECKA_PLAYER, pictureBoxWaveformFull1, m_nCurrentPosInPixels[nPlayerIndex]);
				DrawWaveformScrolling(DECKA_PLAYER, pictureBoxWaveformScroll1);
			}
			else if (nPlayerIndex == DECKB_PLAYER)
			{
				DrawWaveformFull(DECKB_PLAYER, pictureBoxWaveformFull2, m_nCurrentPosInPixels[nPlayerIndex]);
				DrawWaveformScrolling(DECKB_PLAYER, pictureBoxWaveformScroll2);
			}
		}

		private void BtnCue1_1_Click(object sender, EventArgs e)
		{
			ManageCuePoint(DECKA_PLAYER, "Cue Point 1 for player 1", CUE_POINT_PLAYER1_1, BtnCue1_1, BtnCueRec1, BtnCueDel1);
		}

		private void BtnCue2_1_Click(object sender, EventArgs e)
		{
			ManageCuePoint(DECKA_PLAYER, "Cue Point 2 for player 1", CUE_POINT_PLAYER1_2, BtnCue2_1, BtnCueRec1, BtnCueDel1);
		}

		private void BtnCue3_1_Click(object sender, EventArgs e)
		{
			ManageCuePoint(DECKA_PLAYER, "Cue Point 3 for player 1", CUE_POINT_PLAYER1_3, BtnCue3_1, BtnCueRec1, BtnCueDel1);
		}

		private void BtnCue1_2_Click(object sender, EventArgs e)
		{
			ManageCuePoint(DECKB_PLAYER, "Cue Point 1 for player 2", CUE_POINT_PLAYER2_1, BtnCue1_2, BtnCueRec2, BtnCueDel2);
		}

		private void BtnCue2_2_Click(object sender, EventArgs e)
		{
			ManageCuePoint(DECKB_PLAYER, "Cue Point 2 for player 2", CUE_POINT_PLAYER2_2, BtnCue2_2, BtnCueRec2, BtnCueDel2);
		}

		private void BtnCue3_2_Click(object sender, EventArgs e)
		{
			ManageCuePoint(DECKB_PLAYER, "Cue Point 3 for player 2", CUE_POINT_PLAYER2_3, BtnCue3_2, BtnCueRec2, BtnCueDel2);
		}

        private void axGSlider1_Slide(object sender, EventArgs e)
        {
            form1.setSelectedTrackbarValue((int)axGSlider1.Value);
        }

        private void ctl3dPushButton3_Click(object sender, EventArgs e)
        {
            /*
            if (this.form1.IsDisposed)
            {
                this.form1.Refresh();
            }
             */
            this.form1.Show();
            this.form1.Focus();
        }

        private void ctl3dCheckBox1_Click(object sender, EventArgs e)
        {
            this.form1.ShowDialog();
        }

        private void ctl3dCheckBox1_CheckedChanged(object sender, EventArgs e)
        {
            this.form1.setSelectedCheckBoxStatus(((Ctl3dCheckBox)sender).Checked);
        }

        private void ctl3dPushButton1_Click(object sender, EventArgs e)
        {
             MessageBox.Show(loadSample(SAMPLE1_PLAYER, "C:\\a.wav").ToString());
        }

        private void PlayList1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void pictureBoxWaveformScroll1_Click(object sender, EventArgs e)
        {

        }

        private void pictureBoxWaveformFull1_Click(object sender, EventArgs e)
        {

        }

        private void ctl3dPushButton2_Click(object sender, EventArgs e)
        {

        }

        private void ctl3dPushButton2_Click_1(object sender, EventArgs e)
        {
            MessageBox.Show(playSample(SAMPLE1_PLAYER).ToString());
        }
	}

	public class SmartBitmap
	{
		[DllImport("gdi32.dll")]
		public static extern bool DeleteObject(Int32 hObject);

		public Int32 m_hBitmap;

		public SmartBitmap(Bitmap bmp)
		{
			m_hBitmap = bmp.GetHbitmap().ToInt32();
		}

		~SmartBitmap()
		{
			DeleteObject(m_hBitmap);
		}
	}

}
